package com.zbkj.service.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.zbkj.common.constants.WeChatConstants;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.utils.RedisUtil;
import com.zbkj.service.service.WechatService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 微信内容审查工具类
 */
@Service
public class WeChatContentModerationUtil {

    private static final Logger logger = LoggerFactory.getLogger(WeChatContentModerationUtil.class);

    @Autowired
    private WechatService wechatService;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 微信提供的音视频内容安全识别
     * (未做异步消息消费,还用不了!!!!!!!!!!!!!!!!!!!)
     *
     * @param mediaUrl   媒体url
     * @param openId
     * @param media_type 媒体类型
     */
    public void mediaCheckAsync(String mediaUrl, String openId, Integer media_type) {

        // 需要定期获取和更新的访问令牌
        String accessToken = wechatService.getMiniAccessToken();
        //请求参数
        Map<String, String> map = new HashMap<>();
        map.put("openid", openId);
        map.put("scene", "1");//1 资料；2 评论；3 论坛；4 社交日志
        map.put("version", "2");
        map.put("media_url", mediaUrl);
        map.put("media_type", JSONObject.toJSONString(media_type));//1:音频;2:图片
        // 拼接请求URL，使用指定的访问令牌
        String result = HttpUtil.post(StrUtil.format(WeChatConstants.WECHAT_MINI_MEDIA_CHECK_ASYNC_URL, accessToken), JSONObject.toJSONString(map));
        JSONObject jsonObject = JSONObject.parseObject(result);
        //如果accessToken失效,则删除redis中的缓存再获取一次accessToken
        if (jsonObject.getInteger("errcode").equals(40001)) {
            redisUtil.delete(WeChatConstants.REDIS_WECAHT_MINI_ACCESS_TOKEN_KEY);
            accessToken = wechatService.getMiniAccessToken();
            result = HttpUtil.post(StrUtil.format(WeChatConstants.WECHAT_MINI_MEDIA_CHECK_ASYNC_URL, accessToken), JSONObject.toJSONString(map));
            jsonObject = JSONObject.parseObject(result);
        }
        //检查调用微信结果
        checkWechatResult(jsonObject);
    }

    /**
     * 微信提供的文本内容安全识别
     *
     * @param openId
     * @param text
     */
    public void msgSecCheck(String openId, String text) {
        // 需要定期获取和更新的访问令牌
        String accessToken = wechatService.getMiniAccessToken();

        //请求参数
        Map<String, String> map = new HashMap<>();
        map.put("openid", openId);
        map.put("content", text);//需检测的文本内容，文本字数的上限为2500字，需使用UTF-8编码
        map.put("version", "2");
        map.put("scene", "1");//1 资料；2 评论；3 论坛；4 社交日志
        // 拼接请求URL，使用指定的访问令牌
        String result = HttpUtil.post(StrUtil.format(WeChatConstants.WECHAT_MINI_MSG_SEC_CHECK_URL, accessToken), JSONObject.toJSONString(map));
        JSONObject jsonObject = JSONObject.parseObject(result);
        //如果accessToken失效,则删除redis中的缓存再获取一次accessToken
        if (jsonObject.getInteger("errcode").equals(40001)) {
            redisUtil.delete(WeChatConstants.REDIS_WECAHT_MINI_ACCESS_TOKEN_KEY);
            accessToken = wechatService.getMiniAccessToken();
            result = HttpUtil.post(StrUtil.format(WeChatConstants.WECHAT_MINI_MSG_SEC_CHECK_URL, accessToken), JSONObject.toJSONString(map));
            jsonObject = JSONObject.parseObject(result);
        }
        //检查调用微信结果
        checkWechatResult(jsonObject);
    }


    /**
     * 检查调用微信结果
     *
     * @param resultJsonObject 微信返回结果
     */
    private void checkWechatResult(JSONObject resultJsonObject) {
        if (ObjectUtil.isNull(resultJsonObject)) {
            throw new CrmebException("微信小程序接口异常，无返回结果");
        }
        if (!resultJsonObject.containsKey("errcode")) {
            logger.error("微信小程序接口失败，无errcode对象, errmsg = {}", resultJsonObject.getString("errmsg"));
            throw new CrmebException(StrUtil.format("微信小程序接口失败，无errcode对象, errmsg = {}", resultJsonObject.getString("errmsg")));
        }

        if (!resultJsonObject.getInteger("errcode").equals(0)) {
            logger.error("微信小程序接口失败，errcode = {}, errmsg = {}", resultJsonObject.getInteger("errcode"), resultJsonObject.getString("errmsg"));
            logger.error("上传的数据违规，没能通过微信审查");
            throw new CrmebException(StrUtil.format("微信小程序接口失败，errcode = {}, errmsg = {}", resultJsonObject.getInteger("errcode"), resultJsonObject.getString("errmsg")));
        }

        Map<String, Object> map = resultJsonObject.toJavaObject(Map.class);
        // 获取 result 中的 label 值
        if (map.containsKey("result")) {
            Map<String, Object> resultMap = (Map<String, Object>) map.get("result");
            Object suggestObj = resultMap.get("suggest");
            Object labelObj = resultMap.get("label");

            //如果违规就进来
            if (suggestObj != null && labelObj != null && (suggestObj.equals("risky") || suggestObj.equals("review"))) {

                Integer label = null;
                if (labelObj instanceof String) {
                    label = Integer.valueOf((String) labelObj);
                } else if (labelObj instanceof Integer) {
                    label = (Integer) labelObj;
                }

                //20002 色情；20003 辱骂；20006 违法犯罪；20008 欺诈；20012 低俗；20013 版权；
                Set<Integer> violationLabels = new HashSet<>(Arrays.asList(20002, 20003, 20006, 20008, 20012, 20013));
                if (label != null && violationLabels.contains(label)) {
                    logger.error("上传的数据违规，没能通过微信审查，label: " + label);
                    throw new CrmebException("上传的数据违规，拒绝发布");
                }
            }
        }
    }
}
